// Test for the httpModel implementation.
// Copyright 2006 (C) Ralph Thomas

#include <model/error.h>
#include <model/model.h>
#include <model/receiver.h>
#include <model/attributeNames.h>
#include <model/proxy/binder.h>
#include <tests/testCore.h>
#include <toolkit/application.h>
#include <adobe/dictionary.hpp>
#include <adobe/adam.hpp>
#include <stdlib.h>
#ifdef _WINDOWS
#define sleep _sleep
#endif

class wait_receiver : public model::receiver {
  public:
	bool		notified;
	std::string 	topic;
	adobe::value_t	value;

	wait_receiver() : notified( false ) {}
	virtual ~wait_receiver() {}
	virtual void notify( const model::model* m, const std::string& attrName ) {
		notified = true;
		if( !m ) return;
		value = m->getAttribute( attrName );
		topic = attrName;
	}
};

bool testUrl( const std::string& url, const std::string& mime, int ecode ) {
	model::model* m( model::model::fromString( url ) );
	wait_receiver waiter;
	if( !m ) return false;
	m->subscribe( &waiter );
	m->execute( "reload", adobe::value_t() );
	m->getAttribute( model::kType );
	while( !waiter.notified ) {
		toolkit::application::getInstance().doIdle();
		sleep( 1 );
	}
	adobe::value_t error( m->getAttribute( model::kError ) );
	adobe::value_t type( m->getAttribute( model::kType ) );
	bool rval = true;
	if( error != adobe::value_t( ecode ) ) rval = false;
	else if( !ecode && type != adobe::value_t( mime ) ) rval = false;
	m->unsubscribe( &waiter );
	m->release();

	return rval;
}

namespace model {
	//
	/// We try the following things:
	///
	/// 1. Get http://www.yahoo.com/
	/// 2. Get http://bogus.example.com/
	/// 3. Get http://www.google.com/intl/en/images/logo.gif
	//
	class testHttpModel : public test::basic {
	  public:
		const char* performTest() {
			if( !testUrl( "http://www.yahoo.com", "text/html", 0 ) )
				return "Can't fetch www.yahoo.com";
			if( !testUrl( "http://bogus.example.com", "", 6 ) )
				return "Fetched bogus.example.com!";
			if( !testUrl( "http://www.google.com/intl/en/images/logo.gif", "image/gif", 0 ) )
				return "Can't fetch Google logo";
			return 0;
		}
		const char* getTestName() {
			return "testing error codes of HTTP model";
		}
	};
};

void test::runnerSingleton::registerTests() {
	//
	// This sucks. This test doesn't link without this. I hate GCC.
	//
	try {
		adobe::dictionary_t d;
		adobe::sheet_t s;
		adobe::value_t v( model::make_model_binder( d, s ) );
	} catch( ... ) {}
	adoptTest( new model::testHttpModel() );
}

